#include <iostream>

/**
 * C++ 多态
 *
 * 使用多态的优势
 *
 * 代码复用：
 *
 *   通过基类指针或引用，可以操作不同类型的派生类对象，实现代码的复用。
 *
 * 扩展性：
 *
 *  新增派生类时，不需要修改依赖于基类的代码，只需要确保新类正确重写了虚函数。
 *
 * 解耦：
 *
 * 多态允许程序设计更加模块化，降低类之间的耦合度。
 *
 * 注意事项：
 * 1. 只有通过基类的指针或引用调用虚函数时，才会发生多态。
 * 2. 如果直接使用派生类的对象调用函数，那么调用的是派生类中的版本，而不是基类中的版本。
 * 3. 多态性需要运行时类型信息（RTTI），这可能会增加程序的开销。
 *
 *
 *
 * ---------------------------------------- >>>>>>   多态关键字  <<<<<----------------------------------------
 *
 *
 * 虚函数
 *
 *  在基类中声明一个函数为虚函数，使用关键字virtual。
 *  派生类可以重写（override）这个虚函数。
 *  调用虚函数时，会根据对象的实际类型来决定调用哪个版本的函数。
 *
 * 动态绑定
 *
 *  也称为晚期绑定（Late Binding），在运行时确定函数调用的具体实现。
 *  需要使用指向基类的指针或引用来调用虚函数，编译器在运行时根据对象的实际类型来决定调用哪个函数。
 *
 * 纯虚函数
 *
 *  一个包含纯虚函数的类被称为抽象类（Abstract Class），它不能被直接实例化。
 *  纯虚函数没有函数体，声明时使用= 0。
 *  它强制派生类提供具体的实现。
 */

//基类
class Animal{
public:
    //虚函数 sound,为不同的动物发生提供接口
    virtual void sound() const{
        std::cout << "Animal makes a sound" << std::endl;
    }
    //虚析构函数确保子类对象被正确析构
    virtual ~Animal(){
        std::cout << "Animal destroyed" << std::endl;
    }
};

//派生类 Dog，继承自Animal
class Dog : public Animal{
public:
    void sound() const override{
        std::cout << "Dog barks" << std::endl;
    }

    ~Dog(){
        std::cout << "Dog destroyed" << std::endl;
    }
};

//派生类Cat,继承自Animal
class Cat : public  Animal{
public:
    //重写sound方法
    void sound() const override{
        std::cout << "Cat meows" << std::endl;
    }

    ~Cat(){
        std::cout << "Cat destroyed" << std::endl;
    }
};

int main() {
    //基类指针
    Animal *animal;

    //创建Dog对象，并指向 Animal对象
    animal = new Dog();
    animal->sound();    //调用Dog的sound方法
    delete animal;

    //创建Cat对象，并
    animal = new Cat();
    animal->sound();
    delete animal;

    return 0;
}
